/**
 * 表单验证工具函数
 */

/**
 * 验证手机号
 * @param phone 手机号
 * @returns 是否有效
 */
export const isValidPhone = (phone: string): boolean => {
  return /^1[3-9]\d{9}$/.test(phone)
}

/**
 * 验证邮箱
 * @param email 邮箱
 * @returns 是否有效
 */
export const isValidEmail = (email: string): boolean => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}

/**
 * 验证身份证号
 * @param idCard 身份证号
 * @returns 是否有效
 */
export const isValidIdCard = (idCard: string): boolean => {
  return /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/.test(idCard)
}

/**
 * 验证中文姓名
 * @param name 姓名
 * @returns 是否有效
 */
export const isValidChineseName = (name: string): boolean => {
  return /^[\u4e00-\u9fa5]{2,10}$/.test(name)
}

/**
 * 验证URL
 * @param url URL地址
 * @returns 是否有效
 */
export const isValidUrl = (url: string): boolean => {
  try {
    new URL(url)
    return true
  } catch {
    return false
  }
}

/**
 * 验证密码强度
 * @param password 密码
 * @returns 强度等级（0-弱，1-中，2-强）
 */
export const getPasswordStrength = (password: string): number => {
  if (password.length < 6) return 0

  let strength = 0

  // 包含数字
  if (/\d/.test(password)) strength++

  // 包含小写字母
  if (/[a-z]/.test(password)) strength++

  // 包含大写字母
  if (/[A-Z]/.test(password)) strength++

  // 包含特殊字符
  if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) strength++

  // 长度大于8
  if (password.length >= 8) strength++

  if (strength <= 2) return 0 // 弱
  if (strength <= 4) return 1 // 中
  return 2 // 强
}

/**
 * 验证密码（至少8位，包含大小写字母和数字）
 * @param password 密码
 * @returns 是否有效
 */
export const isValidPassword = (password: string): boolean => {
  return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,}$/.test(password)
}

/**
 * 验证车牌号
 * @param plateNumber 车牌号
 * @returns 是否有效
 */
export const isValidPlateNumber = (plateNumber: string): boolean => {
  // 普通车牌 + 新能源车牌
  return /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/.test(
    plateNumber
  )
}

/**
 * 验证银行卡号
 * @param cardNumber 银行卡号
 * @returns 是否有效
 */
export const isValidBankCard = (cardNumber: string): boolean => {
  return /^\d{16,19}$/.test(cardNumber)
}

/**
 * 验证QQ号
 * @param qq QQ号
 * @returns 是否有效
 */
export const isValidQQ = (qq: string): boolean => {
  return /^[1-9]\d{4,10}$/.test(qq)
}

/**
 * 验证微信号
 * @param wechat 微信号
 * @returns 是否有效
 */
export const isValidWechat = (wechat: string): boolean => {
  return /^[a-zA-Z][-_a-zA-Z0-9]{5,19}$/.test(wechat)
}

/**
 * 验证IP地址
 * @param ip IP地址
 * @returns 是否有效
 */
export const isValidIP = (ip: string): boolean => {
  return /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/.test(ip)
}

/**
 * 验证邮政编码
 * @param zipCode 邮政编码
 * @returns 是否有效
 */
export const isValidZipCode = (zipCode: string): boolean => {
  return /^\d{6}$/.test(zipCode)
}

/**
 * 验证固定电话
 * @param tel 固定电话
 * @returns 是否有效
 */
export const isValidTel = (tel: string): boolean => {
  return /^(\d{3,4}-)?\d{7,8}$/.test(tel)
}

/**
 * 验证字符串长度
 * @param str 字符串
 * @param min 最小长度
 * @param max 最大长度
 * @returns 是否在范围内
 */
export const isLengthInRange = (str: string, min: number, max: number): boolean => {
  const length = str.length
  return length >= min && length <= max
}

/**
 * 验证数字范围
 * @param num 数字
 * @param min 最小值
 * @param max 最大值
 * @returns 是否在范围内
 */
export const isNumberInRange = (num: number, min: number, max: number): boolean => {
  return num >= min && num <= max
}

/**
 * 验证是否为空
 * @param value 值
 * @returns 是否为空
 */
export const isEmpty = (value: any): boolean => {
  if (value === null || value === undefined) return true
  if (typeof value === 'string') return value.trim() === ''
  if (Array.isArray(value)) return value.length === 0
  if (typeof value === 'object') return Object.keys(value).length === 0
  return false
}

/**
 * 验证是否为纯数字
 * @param value 值
 * @returns 是否为纯数字
 */
export const isNumeric = (value: any): boolean => {
  return /^\d+$/.test(String(value))
}

/**
 * 验证是否为整数
 * @param value 值
 * @returns 是否为整数
 */
export const isInteger = (value: any): boolean => {
  return Number.isInteger(Number(value))
}

/**
 * 验证是否为正整数
 * @param value 值
 * @returns 是否为正整数
 */
export const isPositiveInteger = (value: any): boolean => {
  return isInteger(value) && Number(value) > 0
}

/**
 * 验证是否包含特殊字符
 * @param str 字符串
 * @returns 是否包含特殊字符
 */
export const hasSpecialChar = (str: string): boolean => {
  return /[!@#$%^&*(),.?":{}|<>]/.test(str)
}

/**
 * 验证是否只包含中文
 * @param str 字符串
 * @returns 是否只包含中文
 */
export const isOnlyChinese = (str: string): boolean => {
  return /^[\u4e00-\u9fa5]+$/.test(str)
}

/**
 * 验证是否只包含英文
 * @param str 字符串
 * @returns 是否只包含英文
 */
export const isOnlyEnglish = (str: string): boolean => {
  return /^[a-zA-Z]+$/.test(str)
}

/**
 * 验证是否只包含英文和数字
 * @param str 字符串
 * @returns 是否只包含英文和数字
 */
export const isAlphanumeric = (str: string): boolean => {
  return /^[a-zA-Z0-9]+$/.test(str)
}

/**
 * 验证文件扩展名
 * @param filename 文件名
 * @param allowedExtensions 允许的扩展名列表
 * @returns 是否为允许的扩展名
 */
export const isValidFileExtension = (filename: string, allowedExtensions: string[]): boolean => {
  const ext = filename.split('.').pop()?.toLowerCase()
  return ext ? allowedExtensions.includes(ext) : false
}

/**
 * 验证图片文件
 * @param filename 文件名
 * @returns 是否为图片文件
 */
export const isImageFile = (filename: string): boolean => {
  return isValidFileExtension(filename, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])
}

/**
 * 验证视频文件
 * @param filename 文件名
 * @returns 是否为视频文件
 */
export const isVideoFile = (filename: string): boolean => {
  return isValidFileExtension(filename, ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'])
}

export default {
  // 常用验证
  isValidPhone,
  isValidEmail,
  isValidIdCard,
  isValidChineseName,
  isValidUrl,
  isValidPassword,
  getPasswordStrength,

  // 其他验证
  isValidPlateNumber,
  isValidBankCard,
  isValidQQ,
  isValidWechat,
  isValidIP,
  isValidZipCode,
  isValidTel,

  // 通用验证
  isLengthInRange,
  isNumberInRange,
  isEmpty,
  isNumeric,
  isInteger,
  isPositiveInteger,
  hasSpecialChar,
  isOnlyChinese,
  isOnlyEnglish,
  isAlphanumeric,

  // 文件验证
  isValidFileExtension,
  isImageFile,
  isVideoFile,
}

